package com.breeze.blockchain.service;

import static com.breeze.blockchain.common.exception.BizErrorCode.USERNAME_OR_PASS_ERROR;
import static com.breeze.blockchain.common.exception.BizErrorCode.USER_NOT_FOUND_ERROR;
import static com.breeze.blockchain.mybatis.entity.table.AdminTable.ADMIN;

import com.breeze.blockchain.common.async.AsyncTaskFactory;
import com.breeze.blockchain.common.enums.LoginStatusEnum;
import com.breeze.blockchain.mybatis.entity.AdminDo;
import com.breeze.components.core.exception.ApiException;
import com.breeze.components.core.thread.ThreadPoolManager;
import com.breeze.components.core.util.web.RequestContextUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import java.time.LocalDateTime;

/**
 * 管理员表 服务层。
 *
 * @author breeze
 * @since 2024-05-11 22:55:04
 */
public interface AdminService extends IService<AdminDo> {

  AdminDo login(String username, String password);

  void saveAdmin(AdminDo admin);

  boolean updateAdmin(AdminDo admin);

  Page<AdminDo> adminPage(Page<AdminDo> toPage, String username, String mobile, String nickname);

  default AdminDo getExistById(Long id) {
    return this.queryChain()
        .where(ADMIN.ID.eq(id))
        .oneOpt()
        .orElseThrow(() -> new ApiException(USER_NOT_FOUND_ERROR));
  }

  default AdminDo getExistUserByUserName(String userName) {
    return queryChain()
        .where(ADMIN.USERNAME.eq(userName).or(ADMIN.MOBILE.eq(userName)))
        .limit(1)
        .oneOpt()
        .orElseThrow(() -> new ApiException(USERNAME_OR_PASS_ERROR));
  }

  default void updateLastLoginInfo(Long loginAdminId) {
    AdminDo admin = this.getById(loginAdminId);
    ThreadPoolManager.execute(
        AsyncTaskFactory.loginInfoTask(
            admin.getUsername(),
            LoginStatusEnum.LOGIN_SUCCESS,
            LoginStatusEnum.LOGIN_SUCCESS.getDesc()));
    updateChain()
        .set(ADMIN.LAST_LOGIN_TIME, LocalDateTime.now())
        .set(ADMIN.LAST_LOGIN_IP, RequestContextUtil.getClientIp())
        .where(ADMIN.ID.eq(loginAdminId))
        .update();
  }
}
